package store

import (
	"codejy/structdef"
	"codejy/utils"
	"fmt"
	"strings"
)

// 函数定义存储 map[string]map[string]def.FuncDefinition   filePath->函数名->函数定义
var funDefinitionStore = utils.NewSyncMap[string, *utils.SyncMap[string, *structdef.FuncDefinition]]()

// 注册函数定义
func RegisterFunDefinition(filePath, funcName string, funDef *structdef.FuncDefinition) {
	//判断函数定义是否已经注册
	get, b := funDefinitionStore.Get(filePath)
	if !b {
		newSyncMap := utils.NewSyncMap[string, *structdef.FuncDefinition]()
		funDefinitionStore.Add(filePath, &newSyncMap)
		get, _ = funDefinitionStore.Get(filePath)
	}
	b1 := get.IsExist(funcName)
	if b1 {
		panic(fmt.Sprintf("函数定义已经注册::::::作用域: %s ,函数名称: %s", filePath, funcName))
	}

	//注册函数定义
	get.Add(funcName, funDef)
	utils.DebugLog("注册函数定义后的信息", func() {
		PrintFunDefinition()
	})
}

// 获取函数定义
func GetFunDefinition(filePath, funcName string) *structdef.FuncDefinition {
	//判断函数定义是否存在
	get, b := funDefinitionStore.Get(filePath)
	if b {
		get1, b1 := get.Get(funcName)
		if b1 {
			return get1
		} else {
			return nil
		}
	} else {
		return nil
	}
}
func GetCurrentFunDefinition(threadStore *structdef.ThreadStore, funcName string) *structdef.FuncDefinition {
	handleFilePath := threadStore.HandleFilePath
	return GetFunDefinition(handleFilePath, funcName)
}

// 打印函数定义
func PrintFunDefinition() {
	funDefinitionStore.Range(func(key string, value *utils.SyncMap[string, *structdef.FuncDefinition]) bool {
		value.Range(func(key1 string, value1 *structdef.FuncDefinition) bool {
			fmt.Printf("作用域:%s----,函数定义->%s\n", key1, value1)
			return true
		})
		return true
	})

}

// 搜索函数定义
func SearchFunDefinition(threadStore *structdef.ThreadStore, funcName string) *structdef.FuncDefinition {
	//判断是否存在点,如果存在那么就表示不是当前文件的函数定义
	if strings.Contains(funcName, ".") {
		//分割
		split := strings.Split(funcName, ".")
		filePath := split[0]
		//获取fileName对应的映射路径
		filePath = GetImportFile(MainFilePath, filePath)
		funcName = split[1]
		return GetFunDefinition(filePath, funcName)
	} else {
		//当前作用域文件中搜索
		return GetCurrentFunDefinition(threadStore, funcName)
	}
}

// 获取所有文件内函数指定注解
func GetFileAllFunAnnotation(annotationName string) map[string]map[string]string {
	annotationMap := make(map[string]map[string]string)
	funDefinitionStore.Range(func(key string, value *utils.SyncMap[string, *structdef.FuncDefinition]) bool {
		value.Range(func(key1 string, value1 *structdef.FuncDefinition) bool {
			if _, ok := value1.Annotations[annotationName]; ok {
				annotationMap[key1] = value1.Annotations[annotationName]
			}
			return true
		})
		return true
	})
	return annotationMap
}

//=========================================================================================================

// 类型定义存储 map[string]map[string]def.TypeDefinition  作用域->类型名->类型定义

var typeDefinitionStore = utils.NewSyncMap[string, *utils.SyncMap[string, *structdef.TypeDefinition]]()

// 注册类型定义
func RegisterTypeDefinition(filePath, typeName string, typeDef *structdef.TypeDefinition) {
	//判断全局函数名,是否和类型名称冲突
	if GetFunDefinition(filePath, typeName) != nil {
		panic(fmt.Sprintf("类型名和函数名冲突:filePath%s---%s", filePath, typeName))
	}

	//判断函数定义是否已经注册
	get, b := typeDefinitionStore.Get(filePath)
	if !b {
		newSyncMap := utils.NewSyncMap[string, *structdef.TypeDefinition]()
		typeDefinitionStore.Add(filePath, &newSyncMap)
		get, _ = typeDefinitionStore.Get(filePath)
	}
	b1 := get.IsExist(typeName)
	if b1 {
		panic(fmt.Sprintf("类型定义已经注册::::::作用域: %s ,类型名称: %s", filePath, typeName))
	}
	get.Add(typeName, typeDef)

	utils.DebugLog("注册类型定义后的信息", func() {
		PrintTypeDefinition()
	})

}

// 获取类型定义
func GetTypeDefinition(filePath, typeName string) *structdef.TypeDefinition {
	//判断类型定义是否存在
	get, b := typeDefinitionStore.Get(filePath)
	if b {
		get1, b1 := get.Get(typeName)
		if b1 {
			return get1
		} else {
			return nil
		}
	} else {
		return nil
	}
}

// 修改类型定义
func UpdateTypeDefinition(filePath, typeName string, typeDef *structdef.TypeDefinition) {
	//判断类型定义是否存在
	get, b := typeDefinitionStore.Get(filePath)
	if b {
		b1 := get.IsExist(typeName)
		if b1 {
			//获取函数定义
			get.Add(typeName, typeDef)
			utils.DebugLog("修改类型定义后的信息", func() {
				PrintTypeDefinition()
			})
		} else {
			panic("类型定义不存在")
		}
	}

}

// 打印类型定义
func PrintTypeDefinition() {

	typeDefinitionStore.Range(func(key string, value *utils.SyncMap[string, *structdef.TypeDefinition]) bool {
		value.Range(func(key1 string, value1 *structdef.TypeDefinition) bool {
			fmt.Printf("作用域:%s----,类型定义->%s\n", key, value1)
			return true
		})
		return true
	})
}

// 搜索类型定义
func SearchTypeDefinition(threadStore *structdef.ThreadStore, typeName string) *structdef.TypeDefinition {
	//判断是否存在点,如果存在那么就表示不是当前文件的函数定义
	if strings.Contains(typeName, ".") {
		//分割
		split := strings.Split(typeName, ".")
		fileName := split[0]
		//获取fileName对应的映射路径
		handleFilePath := threadStore.HandleFilePath
		filePath := GetImportFile(handleFilePath, fileName)
		typeName = split[1]

		return GetTypeDefinition(filePath, typeName)
	} else {
		//获取当前文件名
		handleFilePath := threadStore.HandleFilePath

		return GetTypeDefinition(handleFilePath, typeName)
	}
}

// 获取所有文件内类型指定注解
func GetFileAllTypeAnnotation(annotationName string) map[string]map[string]string {
	annotationMap := make(map[string]map[string]string)
	typeDefinitionStore.Range(func(key string, value *utils.SyncMap[string, *structdef.TypeDefinition]) bool {
		value.Range(func(key1 string, value1 *structdef.TypeDefinition) bool {
			if _, ok := value1.Annotations[annotationName]; ok {
				annotationMap[key1] = value1.Annotations[annotationName]
			}
			return true
		})
		return true
	})
	return annotationMap
}

// 获取指定类型的所有成员属性指定注解
func GetTypeAllPropertiesAnnotation(threadStore *structdef.ThreadStore, typeName, annotationName string) map[string]map[string]string {
	definition := SearchTypeDefinition(threadStore, typeName)
	if definition == nil {
		panic("类型不存在")
	}
	annotationMap := make(map[string]map[string]string)
	for _, property := range definition.Properties {
		if _, ok := property.Annotations[annotationName]; ok {
			annotationMap[property.Name] = property.Annotations[annotationName]
		}
	}
	return annotationMap
}

// 获取指定类型的所有成员方法指定注解
func GetTypeAllMethodsAnnotation(threadStore *structdef.ThreadStore, typeName, annotationName string) map[string]map[string]string {
	definition := SearchTypeDefinition(threadStore, typeName)
	if definition == nil {
		panic("类型不存在")
	}
	annotationMap := make(map[string]map[string]string)
	for methodName, method := range definition.Methods {
		if _, ok := method.Annotations[annotationName]; ok {
			annotationMap[methodName] = method.Annotations[annotationName]
		}
	}
	return annotationMap
}
